﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.IO;

namespace h2100
{
    /// <summary>
    /// Quản lý tất cả các công trình kiến trúc trong game
    /// </summary>
    public class hStructureManager: hEntityManager
    {
        private hStructure[,] _structures;
        public hStructure[,] Structures
        {
            get { return _structures; }
            set { _structures = value; }        
        }

        private hParams args;

        private int _nRows;
        public int NRows
        {
            get { return _nRows; }
            set { _nRows = value; }
        }

        private int _nColumns;
        public int NColumns
        {
            get { return _nColumns; }
            set { _nColumns = value; }
        }

        private Texture2D _txtBackFrontWall;
        private Texture2D _txtLeftWall;
        private Texture2D _txtRightWall;

        public hStructureManager(ContentManager content, hParams _args)
        {
            _txtBackFrontWall = content.Load<Texture2D>(hGlobal.PathSructure + "Wall_front_back");
            _txtLeftWall = content.Load<Texture2D>(hGlobal.PathSructure + "Wall_left");
            _txtRightWall = content.Load<Texture2D>(hGlobal.PathSructure + "Wall_right");

            args = _args;
            _nRows = args.Grid.NRows;
            _nColumns = args.Grid.NColumns;
            _structures = new hStructure[_nRows, _nColumns];            
            initPrototypes(content,args);
        }
                
        /// <summary>
        /// Đọc file cấu hình ("Structure.hcf") các công trình
        /// </summary>
        /// <param name="contentmanager"></param>
        public override void initPrototypes(ContentManager contentmanager, hParams args)
        {
            StreamReader reader = new StreamReader(hGlobal.PathConfig+hGlobal.ConfigStructure);

            _nprototype = int.Parse(reader.ReadLine()) + 1;
            _prototype = new hStructure[_nprototype];   //Bỏ vị trí 0

            for(int i=1;i<_nprototype;i++)
            {
                string name = reader.ReadLine().Split('#')[1];
                String[] arg = reader.ReadLine().Split('=')[1].Trim().Split(' ');
                for (int c = 0; c < arg.Count(); c++)
                {                      
                    arg[c] = hGlobal.PathSructure + arg[c];
                }
                hStructure temp = new hStructure(contentmanager, arg, 0, 0,args.ControlPanel);
                temp.Name = name;
                temp.Power=int.Parse(reader.ReadLine().Split('=')[1]);
                temp.MaxPower = temp.Power;
                temp.Energy = int.Parse(reader.ReadLine().Split('=')[1]);
                temp.Actions = actionParse(reader.ReadLine().Split('=')[1].Split(' '));
                temp.Controler = reader.ReadLine().Split('=')[1];
                temp.TerrainType = reader.ReadLine().Split('=')[1].Split(' ');
                temp.Cost = (Math.Abs(temp.Energy) + Math.Abs(temp.Power)) * 2;
                _prototype[i] = temp;
            }

            reader.Close();

        }
        
        //public override hVisibleGameEntity createObject(int idx)
        //{
        //    if (idx < 0 || idx >= _nprototype)
        //        return null;
        //    _structures.Add((hStructure)_prototype[idx].clone());
        //    return _structures.Last();
        //}

        /// <summary>
        /// Tạo công trình tại ô chỉ định
        /// </summary>
        /// <param name="idx">Chỉ số mẫu (công trình nào)</param>
        /// <param name="iRow">Chỉ số dòng</param>
        /// <param name="iColumn">Chỉ số cột</param>
        /// <returns></returns>        
        public void createObject(int idx, int iRow, int iColumn)
        {
            if (idx < 1 || idx >= _nprototype)
                return;
            hStructure s = (hStructure)((hStructure)_prototype[idx]).clone(args);
            
            float delta=0;
            if (s.Height > hGlobal.MapCellHeight)
                delta = hGlobal.MapCellHeight - s.Height;

            s.X = args.Grid.Grid[iRow, iColumn].X;
            s.Y = args.Grid.Grid[iRow,iColumn].Y - delta;
            
            _structures[iRow,iColumn] = s;
        }

        public void AddStructure(ContentManager content, String[] argStateTexture, int iRow, int iColumn)
        {
            hStructure tmp = new hStructure(content, argStateTexture, args.Grid.Grid[iRow, iColumn].X, args.Grid.Grid[iRow, iColumn].Y, args.ControlPanel);
            _structures[iRow, iColumn] = tmp;
        }

        public void update(hParams args, GameTime gameTime)
        {
            for (int i = 0; i < _nRows; i++)
            {
                for (int j = 0; j < _nColumns; j++)
                {
                    if (_structures[i, j] != null)
                    {
                        _structures[i, j].update(args, gameTime);
                        if (_structures[i, j].IsDead)
                        {
                            _structures[i, j] = null;
                            args.MapManager.Map.MapCells[i, j].isFreeToBuild = true;
                        }
                        else
                        {
                            if (args.ControlPhase != hGlobal.ControlPhase.Selecting)
                            {
                                if (_structures[i, j].Clicked)
                                {
                                    args.SelectedStructure = _structures[i, j];
                                }
                                _structures[i, j].Selected = false;
                            }
                        }
                    }
                }
            }
            if (args.SelectedStructure != null)
            {
                args.SelectedStructure.Selected = true;
                if (args.SelectedUnit != null)
                {
                    args.SelectedUnit.Selected = false;
                    args.SelectedUnit = null;
                }
                if (args.SelectedStructureHasChanged)
                {
                    args.ControlPhase = hGlobal.ControlPhase.Action;
                }
            }
            else 
            {
                if (args.ControlPhase != hGlobal.ControlPhase.Selecting)
                {
                    args.SelectedStructure = null;
                    //args.SelectedStructureIndex = -1;
                    args.ControlPhase = hGlobal.ControlPhase.NoAction;
                }
            }
        }       

        public void draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            for (int i = 0; i < _nRows; i++)
            {
                for (int j = 0; j < _nColumns; j++)
                {
                    if (_structures[i, j] != null)
                    {
                        // TODO: nền công trình

                        //tường sau
                        if (_structures[i, j].Controler.Equals("player"))
                        {
                            if ((i == 0)
                                || ((i > 0) && ((_structures[i - 1, j] == null)
                                                || (_structures[i - 1, j] != null && !_structures[i - 1, j].Controler.Equals("player")))))
                            {
                                spriteBatch.Draw(_txtBackFrontWall, new Vector2(args.MapManager.Map.MapCells[i, j].X, args.MapManager.Map.MapCells[i, j].Y), new Color(255, 255, 255, 100));
                            }
                        }

                        // công trình
                        _structures[i, j].draw(gameTime, spriteBatch);
                        //tường trước và hai bên
                        if (_structures[i, j].Controler.Equals("player"))
                        {
                            if ((i == _nRows - 1)
                                || ((i < _nRows - 1) && ((_structures[i + 1, j] == null)
                                                            || (_structures[i + 1, j] != null && !_structures[i + 1, j].Controler.Equals("player")))))
                            {
                                spriteBatch.Draw(_txtBackFrontWall, new Vector2(args.MapManager.Map.MapCells[i, j].X, args.MapManager.Map.MapCells[i, j].Y + (hGlobal.MapCellHeight - _txtBackFrontWall.Height)), new Color(255, 255, 255, 100));
                            }

                            if (((j == 0)
                                || ((j > 0) && ((_structures[i, j - 1] == null)
                                                || _structures[i, j - 1] != null && !_structures[i, j - 1].Controler.Equals("player")))))
                            {
                                spriteBatch.Draw(_txtLeftWall, new Vector2(args.MapManager.Map.MapCells[i, j].X, args.MapManager.Map.MapCells[i, j].Y), new Color(255, 255, 255, 100));
                            }

                            if ((j == _nColumns - 1)
                                || ((j < _nColumns - 1) && ((_structures[i, j + 1] == null)
                                                            || (_structures[i, j + 1] != null && !_structures[i, j + 1].Controler.Equals("player")))))
                            {
                                spriteBatch.Draw(_txtRightWall, new Vector2(args.MapManager.Map.MapCells[i, j].X + (hGlobal.MapCellWidth - _txtRightWall.Width), args.MapManager.Map.MapCells[i, j].Y), new Color(255, 255, 255, 100));
                            }
                        }
                    }
                }
            }
        }

        public int getEnergy()
        {
            int t=0;
            for (int i = 0; i < _nRows; i++)
            {
                for (int j = 0; j < _nColumns; j++)
                {
                    if (_structures[i, j] != null)
                    {
                        t += _structures[i, j].Energy;
                    }
                }
            }
            return t;
        }
        
    }
}
